package com.suixuan.spring.service.impl.security;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.RegexUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.suixuan.support.cache.CacheApplicationManager;

/**
 * 
 * @Copyright (c) Nanjing Zhou Su co.,Ltd
 * 
 * @Project oa
 * @Title SecureResourceFilterInvocationDefinitionSource.java
 * @Package com.suixuan.spring.service.impl.security
 * @Description 安全资源过滤器调用的来源定义
 * @Author suixuan
 * @Editors 1
 * @Date 2010-11-29 上午09:02:11
 * @Note
 * @Version:1.0.0
 * 
 */
@Service
public class SecureResourceFilterInvocationDefinitionSource implements FilterInvocationSecurityMetadataSource,
		InitializingBean {

	private UrlMatcher urlMatcher = new RegexUrlPathMatcher();

	private boolean useAntPath = true;

	private boolean lowercaseComparisons = true;

	/**
	 * 缓存接口
	 */
	@Resource
	private CacheApplicationManager cacheApplicationManager;

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		// guess object is a URL.
		Map<String, Collection<ConfigAttribute>> cacheResourceMap = null;
		// cacheResourceMap =
		// this.cacheApplicationManager.getAppCache(CacheKeyConstant.SYSTEM_SECURITY_PERMISSIONS_CACHE,
		// Map.class);
		cacheResourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		// 通过数据库中的信息设置，resouce和role
		// 把资源放入到 spring security的resouceMap中
		String url = ((FilterInvocation) object).getRequestUrl();

		// 将spring mvc 前缀去除
		// url = url.replaceFirst(ConstantUtils.SPRING_MVC_PREFIX,
		// ConstantUtils.EMPTY_STRING);
		if (CollectionUtils.isEmpty(cacheResourceMap)) {
			return null;
		}

		Set<Map.Entry<String, Collection<ConfigAttribute>>> configAtt = cacheResourceMap.entrySet();
		for (Map.Entry<String, Collection<ConfigAttribute>> entry : configAtt) {
			String resURL = entry.getKey();
			if (!StringUtils.hasText(resURL)) {
				continue;
			}
			if (urlMatcher.pathMatchesUrl(resURL, url)) {
				// return entry.getValue();
				return null;
			}
		}
		// throw new AccessDeniedException(notAccess);

		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// default url matcher will be RegexUrlPathMatcher

		if (useAntPath) { // change the implementation if required
			this.urlMatcher = new AntUrlPathMatcher();
		}

		// Only change from the defaults if the attribute has been set
		if (true == lowercaseComparisons) {
			if (!this.useAntPath) {
				((RegexUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(true);
			}
		} else if (false == lowercaseComparisons) {
			if (this.useAntPath) {
				((AntUrlPathMatcher) this.urlMatcher).setRequiresLowerCaseUrl(false);
			}
		}

	}

	@PostConstruct
	public void loadResourceDefine() {

		// 通过数据库中的信息设置，resouce和role

		// 把资源放入到 spring security的resouceMap中

		// 系统中所
	}

	public void setUrlMatcher(UrlMatcher urlMatcher) {
		this.urlMatcher = urlMatcher;
	}

	public void setUseAntPath(boolean useAntPath) {
		this.useAntPath = useAntPath;
	}

	public void setLowercaseComparisons(boolean lowercaseComparisons) {
		this.lowercaseComparisons = lowercaseComparisons;
	}

	/**
	 * @return the urlMatcher
	 */
	public UrlMatcher getUrlMatcher() {
		return urlMatcher;
	}

	/**
	 * @return the useAntPath
	 */
	public boolean isUseAntPath() {
		return useAntPath;
	}

	/**
	 * @return the lowercaseComparisons
	 */
	public boolean isLowercaseComparisons() {
		return lowercaseComparisons;
	}

}
